#include <iostream>
#include <vector>
using namespace std;

class seg_tree {
        int size;
        vector<long> imax;
        vector<long> ladd;
        vector<long> lupdate;
        vector<bool> isupdate;

        void build(vector<long> &val, int l, int r, int i)
        {       
                if(l == r){
                        imax[i] = val[l];
                }else{
                        int mid = (l + r) >> 1;
                        build(val, l, mid, i << 1);
                        build(val, mid + 1, r, i << 1 | 1);
                        up(i);
                }
        }

        void up(int i)
        {
                imax[i] = max(imax[i << 1], imax[i << 1 | 1]);
        }

        void down(int i)
        {
                if(isupdate[i]){
                        lazyupdate(i << 1, lupdate[i]);
                        lazyupdate(i << 1 | 1, lupdate[i]);
                        isupdate[i] = false;
                }
                if(ladd[i]){
                        lazyadd(i << 1, ladd[i]);
                        lazyadd(i << 1 | 1, ladd[i]);
                        ladd[i] = 0;
                }
        }

        void lazyadd(int i, long v)
        {
                imax[i] += v;
                ladd[i] += v;
        }

        void lazyupdate(int i, long v)
        {
                ladd[i] = 0;
                imax[i] = v;
                lupdate[i] = v;
                isupdate[i] = true;
        }
public:
        seg_tree(vector<long> &val)
        :size(val.size() - 1), imax(size<<2, 0), ladd(size<<2, 0), lupdate(size<<2, 0), isupdate(size<<2, false)
        {
                build(val, 1, size, 1);
        }

        void add(int tl, int tr, long v, int l, int r, int i)
        {
                if(tl <= l && r <= tr){
                        lazyadd(i, v);
                }else{
                        int mid = (l + r) >> 1;
                        down(i);
                        if(tl <= mid){
                                add(tl, tr, v, l, mid, i << 1);
                        }
                        if(mid < tr){
                                add(tl, tr, v, mid + 1, r, i << 1 | 1);
                        }
                        up(i);
                }
        }

        void update(int tl, int tr, long v, int l, int r, int i)
        {
                if(tl <= l && r <= tr){
                        lazyupdate(i, v);
                }else{
                        int mid = (l + r) >> 1;
                        down(i);
                        if(tl <= mid){
                                update(tl, tr, v, l, mid, i << 1);
                        }
                        if(mid < tr){
                                update(tl, tr, v, mid + 1, r, i << 1 | 1);
                        }
                        up(i);
                }
        }

        long query(int tl, int tr, int l, int r, int i)
        {
                if(tl <= l && r <= tr){
                        return imax[i];
                }
                int mid = (l + r) >> 1;
                down(i);
                long ansl = INT64_MIN, ansr = INT64_MIN;
                if(tl <= mid){
                        ansl = query(tl, tr, l, mid, i << 1);
                }
                if(mid < tr){
                        ansr = query(tl, tr, mid + 1, r, i << 1 | 1);
                }
                return max(ansl, ansr);
        }
};

int main()
{
        ios::sync_with_stdio(0);
        cin.tie(0);
        cout.tie(0);
        
        int n, m;
        cin>>n>>m;
        vector<long> val(n + 1, 0);
        for(int i = 1; i <= n; i++){
                cin>>val[i];
        }
        seg_tree st(val);
        int op, l, r;
        long x;
        for(int i = 0; i < m; i++){
                cin>>op>>l>>r;
                if(op == 1){
                        cin>>x;
                        st.update(l, r, x, 1, n, 1);
                }else if(op == 2){
                        cin>>x;
                        st.add(l, r, x, 1, n, 1);
                }else{
                        cout<<st.query(l, r, 1, n, 1)<<endl;
                }
        }
        return 0;
}